--[[	$Id: caelBuffet.lua 3283 2013-05-22 10:22:48Z sdkyron@gmail.com $	]]

local _, caelBuffet = ...

Buffet = CreateFrame("Frame", nil, UIParent)

local macroHP = "#showtooltip\n%MACRO%"
local macroMP = "#showtooltip\n%MACRO%"

local bests, items, allitems, dirty = {}, {}, {}

for i, v in pairs(caelBuffet) do
	items[i] = v
end

local function TableStuffer(...)
	local t = {}
	for i = 1, select("#", ...) do
		local id, v = string.split(":", (select(i, ...)))

		if id and id ~= "" then
			t[tonumber(id)] = tonumber(v) or 0
			allitems[tonumber(id)] = tonumber(v) or 0
		end
	end

	return t
end

for i, v in pairs(items) do
	bests[i] = {}
	items[i] = TableStuffer(string.split("\n", v))
end

Buffet.Scan = function()
	for _, t in pairs(bests) do
		for i in pairs(t) do
			t[i] = nil
		end
	end
	
	local mylevel = UnitLevel("player")

	for bag = 0, 4 do
		for slot = 1, GetContainerNumSlots(bag) do
			local link = GetContainerItemLink(bag, slot)
			local id = (link and string.find(link, "item:(%d+)")) and tonumber(select(3, string.find(link, "item:(%d+)")))

			local reqlvl = link and select(5, GetItemInfo(link)) or 0

			if id and allitems[id] and reqlvl <= mylevel then
				local _, stack = GetContainerItemInfo(bag,slot)

				for set, setitems in pairs(items) do
					local thisbest, val = bests[set], setitems[id]
					if val and (not thisbest.val or (thisbest.val < val or thisbest.val == val and thisbest.stack > stack)) then
						thisbest.id, thisbest.val, thisbest.stack = id, val, stack
					end
				end
			end
		end
	end

	local food = bests.conjfood.id or bests.percfood.id or bests.food.id or bests.hstone.id or bests.hppot.id
	local water = bests.conjwater.id or bests.percwater.id or bests.water.id or bests.mstone.id or bests.mppot.id

	Buffet.Edit("AutoHP", macroHP, food, bests.hppot.id, bests.hstone.id, bests.bandage.id)
	Buffet.Edit("AutoMP", macroMP, water, bests.mppot.id, bests.mstone.id)

	dirty = false
end

Buffet.Edit = function(name, substring, food, pot, stone, shift)
	local macroid = GetMacroIndexByName(name)

	if not macroid then return end

	local body = "/use "
	if shift then body = body .. "[mod:shift,target=player] item:"..shift.."; " end
	if (pot and not stone) or (stone and not pot) then body = body .. "[combat] item:"..(pot or stone).."; " end
	body = body .. (pot and stone and "[nocombat] " or "").."item:"..(food or "6948")

	if pot and stone then body = body .. "\n/castsequence [combat,nomod] reset="..(stone == 22044 and "120/" or "").."combat item:"..stone..", item:"..pot end

	EditMacro(macroid, name, "INV_Misc_QuestionMark", substring:gsub("%%MACRO%%", body), 1)
end

Buffet:SetScript("OnEvent", function(self, event, ...)
	if event == "PLAYER_LOGIN" then
		self:Scan()
	elseif event == "PLAYER_REGEN_ENABLED" then
		if dirty then
			Buffet.Scan(self)
		end
	elseif event == "BAG_UPDATE" or event == "PLAYER_LEVEL_UP" then
		dirty = true

		if not InCombatLockdown() then
			Buffet.Scan(self)
		end
	end
end)

for _, event in next, {
	"PLAYER_LOGIN",
	"PLAYER_REGEN_ENABLED",
	"BAG_UPDATE",
	"PLAYER_LEVEL_UP",
} do
	Buffet:RegisterEvent(event)
end